#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Copyright © 启明星辰 版权所有
# @Time    : 2023/5/15 10:59
# @Author  : 胡浩浩
# @Email   : hu_haohao@venusgroup.com.cn
# @File    : case_tools.py
# @IDE     : PyCharm
# @description :
import json
import os
import time
import jmespath
import allure
import jsonpath
from ruamel import yaml
from commons.json_tools import read_file, write_to_file
from commons.yaml_tools import append_write_to_yml

func_data_path = "data/func_data.json"
variables_data_path = "data/variables_data.json"
extract_global_variable_data_path = "extract_global_variable.yml"
test_suite_temp_path = "frontend/templates/test_suite.pytemp"
test_step_temp_path = "frontend/templates/test_step.pytemp"
setup_temp_path = "frontend/templates/setup.pytemp"
teardown_temp_path = "frontend/templates/teardown.pytemp"


# def handle_params(data):
#     print("开始处理参数")
#     str_data = json.dumps(data, ensure_ascii=False)
#     print(str_data)
#     re_comp = re.compile("\$\{(.*?)}\$", re.S)
#     re_result = re.findall(re_comp, str_data)
#     print("找到了这么多需要替换的:", re_result)
#     func_data_json = read_json_file(func_data_path)
#     variables_data_list = read_json_file(variables_data_path)
#     print("func_data_json", func_data_json)
#     if re_result:
#         for item in re_result:
#             print(item)
#             if "(" in item and ")" in item:
#                 func_name = item[:item.index("(")]
#                 print(func_name)
#                 params = item[item.index("(") + 1:item.index(")")]
#                 print(params)
#                 params = '"' + params.replace(',', '","') + '"'
#                 func_result = jmespath.search(f'@.*|[?@[1]==`"{func_name}"`]', func_data_json)
#                 print("2222", func_result)
#                 exec(func_result[0][2])
#                 result = eval(item)
#                 print("result", result)
#                 if isinstance(result, str) or isinstance(result, int):
#                     str_data = str_data.replace("${" + item + "}$", str(result))
#                 if isinstance(result, dict):
#                     str_data = str_data.replace("\"${" + item + "}$\"", json.dumps(result, ensure_ascii=False))
#             else:
#                 print("处理全局变量或者局部变量")
#                 # 从全局变量variables_data.json中取数据进行替换,或者从全局提取变量文件extract_global_variable.yml中取数据
#
#                 print(variables_data_list)
#                 print(type(variables_data_list))
#                 print(item)
#                 print(type(item))
#                 print(f"@.*|[?@[0]==`{item}`][1]|[0]")
#                 result = jmespath.search(f'@.*|[?@[0]==`"{item}"`][1]|[0]', variables_data_list)
#                 print("数据提取出来了................", result)
#                 if result:
#                     str_data = str_data.replace("${" + item + "}$", str(result))
#                     print(str_data)
#                 else:
#                     variable = read_yml(extract_global_variable_data_path)
#                     print("extract_global_variable_data_path-----------", variable.get(item))
#                     if variable.get(item):
#                         str_data = str_data.replace("${" + item + "}$", str(variable.get(item)))
#
#     new_data = json.loads(str_data)
#     return new_data


def extract_data(express, response):
    print("数据提取开始-------------------")
    print(express)
    print(response)
    extract_data_list = []
    if express:
        for key, value in express.items():
            print(key)
            print(value)
            if response.json():
                if str(value).startswith("$"):
                    extract_result = jsonpath.jsonpath(value, response.json())
                    print(extract_result)
                else:
                    print("我一定没有被执行到--------------1111111111111")
                    extract_result = jmespath.search(value, response.json())
                    print(extract_result)
                    print({key: extract_result})
                    if extract_result:
                        append_write_to_yml(extract_global_variable_data_path, {key: extract_result})
                        extract_data_list.append({key: extract_result})
                        print("我一定没有被执行到--------------")

        print("数据提取结束--------------------")
    return extract_data_list


def response_asset(asset_express, response):
    print("断言开始--------------------------")
    print(asset_express)
    print(response.text)
    if asset_express:
        assert_flag = False
        assert_result_fail = ""
        assert_result_success = ""
        for key, value in asset_express.items():
            if key == "code":
                if response.status_code != value:
                    print("我在断言code,我没有执行吗?")
                    assert_result_fail += f"code断言: 接口返回: {str(response.status_code)}!=期望结果{str(value)}\n"
                    assert_flag = True
                else:
                    assert_result_success += f"code断言: 接口返回: {str(response.status_code)}==期望结果{str(value)}\n"
            elif key == "equals":
                for e_k, e_v in value.items():
                    actual_result = jmespath.search(f"{e_k}", response.json())
                    print(e_k)
                    print(e_v)
                    if actual_result != e_v:
                        assert_result_fail += f"equals断言: 接口返回: {e_k} 实际值为{actual_result}!=期望结果{str(e_v)}\n"
                        assert_flag = True
                    else:
                        assert_result_success += f"equals断言: 接口返回: {e_k} 实际值为{actual_result}==期望结果{str(e_v)}\n"
            elif key == "contains":
                for item in value:
                    if str(item) not in response.text:
                        assert_result_fail += f"contains断言: 接口返回: 不包含期望内容{item}\n"
                        assert_flag = True
                    else:
                        assert_result_success += f"contains断言: 接口返回: 包含期望内容{item}\n"
                pass
            elif key == "calculation":
                for item in value:
                    assert_result = eval(item)
                    if not assert_result:
                        assert_result_fail += f"calculation断言: 计算失败:{item}\n"
                        assert_flag = True
                    else:
                        assert_result_success += f"calculation断言: 计算成功:{item}\n"
        if assert_flag:
            print(assert_result_fail)
            allure.attach(assert_result_fail, "断言失败")
            raise AssertionError("断言失败")
        else:
            allure.attach(assert_result_success, "断言成功")
    print("断言结束--------------------------")


def send_request(session, case, host):
    print("case_list--------------------------", case)
    case.get("wai_time")
    time.sleep(case.get("wait_time") if case.get("wait_time") else 0.0)
    allure.attach(str(case.get("wait_time")) if case.get("wait_time") else str(0.0) + "ms", "等待时间:")
    # case = handle_params(case)
    print("..................................")
    print(case)
    method = case["request"].get("method")
    headers = case["request"].get("headers")
    data = case["request"].get("data")

    params = case["request"].get("params")
    url = host + case["request"]["path"]
    print("请求参数:--------------------", method)
    print("请求参数:--------------------", headers)
    print("请求参数:--------------------", data)
    print("请求参数:--------------------", params)
    print("请求参数:--------------------", url)
    if headers.get("Content-Type") and "application/json" in headers.get("Content-Type"):
        response = session.request(method=method, url=url, headers=headers, params=params, json=data, verify=False)
    else:
        response = session.request(method=method, url=url, headers=headers, params=params, data=data, verify=False)

    # 测试报告富化
    print("接口响应数据", response.text)
    allure.attach(url, "请求url")
    allure.attach(method, "请求方法")
    allure.attach(json.dumps(headers, ensure_ascii=False, indent=4), "请求头")
    allure.attach(data if isinstance(data, str) else json.dumps(data, ensure_ascii=False, indent=4),
                  "请求参数data")
    allure.attach(params if isinstance(params, str) else json.dumps(params, ensure_ascii=False, indent=4),
                  "请求参数params")
    # allure.attach(json.dumps(response.json(), ensure_ascii=False, indent=4), "响应信息:")

    # 变量提取
    # extract_data_list = extract_data(case["save_vars"], response)
    # allure.attach(json.dumps(extract_data_list,ensure_ascii=False,indent=4), "变量提取:")

    # 接口断言
    # 系统默认200断言
    # response_asset(case["checker"], response)


def create_config(data):
    """
        通过测试环境绑定的登录模板，生成对应的config.py文件
    """

    pass


def create_test_case(yml_case_file_list: list):
    """
        结合测试用例模板和测试用例参数，生成对应的测试用例py文件
    """
    # print(yml_case_file_list)
    test_case_dir = f"autotest/{int(time.time() * 1000)}"
    os.mkdir(test_case_dir)
    for yml_case_data in yml_case_file_list:
        print(yml_case_data)
        yml_case = yaml.load(yml_case_data["content"], Loader=yaml.UnsafeLoader)
        py_file_name = yml_case_data["filename"].split(".")[0]
        print(yml_case)
        test_suite_temp = read_file(test_suite_temp_path)
        print(test_suite_temp)
        test_suite_temp = test_suite_temp.replace("{{suite_name}}", py_file_name).replace("{{suite_desc}}",
                                                                                          yml_case[
                                                                                              "suite_desc"])
        write_to_file(f"{test_case_dir}/test_{py_file_name}.py", test_suite_temp, "a")
        for case in yml_case["test_steps"]:
            """
                参数处理需要在发送请求之前处理,否则,动态提取的参数无法在第一时间进行获取到
            """
            # case = handle_params(json.dumps(case, ensure_ascii=False))
            case["request"]["url"] = case["request"]["url"]
            print("转化后的参数", case)
            setup_temp = read_file(setup_temp_path)
            teardown_temp = read_file(teardown_temp_path)
            test_step_temp = read_file(test_step_temp_path)
            if case["request"].get("setup"):
                write_to_file(f"{test_case_dir}/test_{py_file_name}.py", setup_temp, "a")
            if case["request"].get("teardown"):
                write_to_file(f"{test_case_dir}/test_{py_file_name}.py", teardown_temp, "a")
            test_step_temp = test_step_temp.replace("{{step_desc}}", case["step_desc"]).replace("{{case_info}}",
                                                                                                str([case])).replace(
                "{{step_name}}",

                case["step_name"].replace("${", "").replace("}$", "") if "${" in case["step_name"] else case[
                    "step_name"])
            write_to_file(f"{test_case_dir}/test_{py_file_name}.py", test_step_temp, "a")
